<!--
~  Licensed to the Apache Software Foundation (ASF) under one or more
~  contributor license agreements.  See the NOTICE file distributed with
~  this work for additional information regarding copyright ownership.
~  The ASF licenses this file to You under the Apache License, Version 2.0
~  (the "License"); you may not use this file except in compliance with
~  the License.  You may obtain a copy of the License at
~
~     http://www.apache.org/licenses/LICENSE-2.0
~
~  Unless required by applicable law or agreed to in writing, software
~  distributed under the License is distributed on an "AS IS" BASIS,
~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~  See the License for the specific language governing permissions and
~  limitations under the License.
-->

@if (accessPolicyState$ | async; as accessPolicyState) {
    @if (isInitialLoading(accessPolicyState)) {
        <div>
            <ngx-skeleton-loader count="3"></ngx-skeleton-loader>
        </div>
    } @else {
        @if (flowConfiguration$ | async; as flowConfiguration) {
            <div class="global-access-policies flex flex-col h-full">
                <context-error-banner [context]="ErrorContextKey.ACCESS_POLICIES"></context-error-banner>
                <div class="flex justify-between items-center">
                    <div>
                        <form [formGroup]="policyForm" class="my-2">
                            <div class="flex gap-x-2">
                                <div class="resource-select">
                                    <mat-form-field subscriptSizing="dynamic">
                                        <mat-label>Policy</mat-label>
                                        <mat-select
                                            formControlName="resource"
                                            (selectionChange)="resourceChanged($event.value)">
                                            @for (option of resourceOptions; track option) {
                                                <mat-option
                                                    [value]="option.value"
                                                    nifiTooltip
                                                    [tooltipComponentType]="TextTip"
                                                    [tooltipInputData]="option.description"
                                                    [delayClose]="false"
                                                    >{{ option.text }}
                                                </mat-option>
                                            }
                                        </mat-select>
                                    </mat-form-field>
                                </div>
                                @if (supportsResourceIdentifier) {
                                    <div class="resource-identifier-select">
                                        <mat-form-field subscriptSizing="dynamic">
                                            <mat-label>Option</mat-label>
                                            <mat-select
                                                formControlName="resourceIdentifier"
                                                (selectionChange)="resourceIdentifierChanged()">
                                                @for (option of requiredPermissionOptions; track option) {
                                                    <mat-option
                                                        [value]="option.value"
                                                        nifiTooltip
                                                        [tooltipComponentType]="TextTip"
                                                        [tooltipInputData]="option.description"
                                                        [delayClose]="false"
                                                        >{{ option.text }}
                                                    </mat-option>
                                                }
                                            </mat-select>
                                        </mat-form-field>
                                    </div>
                                }
                                <div class="action-select" [class.hidden]="!supportsReadWriteAction">
                                    <mat-form-field subscriptSizing="dynamic">
                                        <mat-label>Action</mat-label>
                                        <mat-select formControlName="action" (selectionChange)="actionChanged()">
                                            <mat-option [value]="Action.Read">view</mat-option>
                                            <mat-option [value]="Action.Write">modify</mat-option>
                                        </mat-select>
                                    </mat-form-field>
                                </div>
                            </div>
                        </form>
                        <div class="tertiary-color font-medium my-2">
                            <div>
                                @switch (accessPolicyState.policyStatus) {
                                    @case (PolicyStatus.NotFound) {
                                        No policy for the specified resource.
                                        @if (flowConfiguration.supportsConfigurableAuthorizer) {
                                            <a (click)="createNewPolicy()">Create</a> a new policy.
                                        }
                                    }
                                    @case (PolicyStatus.Inherited) {
                                        @if (accessPolicyState.accessPolicy) {
                                            <ng-container
                                                *ngTemplateOutlet="
                                                    getTemplateForInheritedPolicy(accessPolicyState.accessPolicy);
                                                    context: {
                                                        $implicit: accessPolicyState.accessPolicy,
                                                        supportsConfigurableAuthorizer:
                                                            flowConfiguration.supportsConfigurableAuthorizer
                                                    }
                                                "></ng-container>
                                        }
                                    }
                                    @case (PolicyStatus.Forbidden) {
                                        Not authorized to access the policy for the specified resource.
                                    }
                                }
                            </div>
                        </div>
                    </div>
                    @if (flowConfiguration.supportsConfigurableAuthorizer) {
                        <div class="flex gap-x-2 items-center">
                            <button
                                mat-icon-button
                                class="primary-icon-button"
                                title="Add users/groups to this policy"
                                [disabled]="accessPolicyState.policyStatus !== PolicyStatus.Found"
                                (click)="addTenantToPolicy()">
                                <i class="fa fa-user-plus"></i>
                            </button>
                            <button
                                mat-icon-button
                                class="primary-icon-button"
                                title="Delete this policy"
                                [disabled]="accessPolicyState.policyStatus !== PolicyStatus.Found"
                                (click)="deletePolicy()">
                                <i class="fa fa-trash"></i>
                            </button>
                        </div>
                    }
                </div>
                @if (currentUser$ | async; as user) {
                    <div class="flex-1">
                        <policy-table
                            [policy]="accessPolicyState.accessPolicy"
                            [supportsPolicyModification]="
                                flowConfiguration.supportsConfigurableAuthorizer &&
                                accessPolicyState.policyStatus === PolicyStatus.Found
                            "
                            (removeTenantFromPolicy)="removeTenantFromPolicy($event)"></policy-table>
                    </div>
                }
                <div class="flex justify-between mt-2">
                    <div class="text-sm flex items-center gap-x-2">
                        <button mat-icon-button class="primary-icon-button" (click)="refreshGlobalAccessPolicy()">
                            <i class="fa fa-refresh" [class.fa-spin]="accessPolicyState.status === 'loading'"></i>
                        </button>
                        <div>Last updated:</div>
                        <div class="tertiary-color font-medium">
                            {{ accessPolicyState.loadedTimestamp }}
                        </div>
                    </div>
                </div>
            </div>
        }
    }
}
<ng-template #inheritedFromPolicies let-policy let-supportsConfigurableAuthorizer="supportsConfigurableAuthorizer">
    Showing effective policy inherited from all policies.
    @if (supportsConfigurableAuthorizer) {
        <a (click)="overridePolicy()">Override</a> this policy.
    }
</ng-template>
<ng-template #inheritedFromController let-policy let-supportsConfigurableAuthorizer="supportsConfigurableAuthorizer">
    Showing effective policy inherited from the controller.
    @if (supportsConfigurableAuthorizer) {
        <a (click)="overridePolicy()">Override</a> this policy.
    }
</ng-template>
<ng-template
    #inheritedFromNoRestrictions
    let-policy
    let-supportsConfigurableAuthorizer="supportsConfigurableAuthorizer">
    No restriction specific users.
    @if (supportsConfigurableAuthorizer) {
        <a (click)="createNewPolicy()">Create</a> a new policy.
    }
</ng-template>
